package com.ikingtech.platform.business.message.controller;

import com.ikingtech.framework.sdk.base.model.BatchParam;
import com.ikingtech.framework.sdk.base.model.PageResult;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.context.exception.FrameworkException;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.enums.message.MessageReadStatusEnum;
import com.ikingtech.framework.sdk.message.api.MessageManagementApi;
import com.ikingtech.framework.sdk.message.model.MessageDTO;
import com.ikingtech.framework.sdk.message.model.MessageQueryParamDTO;
import com.ikingtech.framework.sdk.message.model.rpc.MessageSendParam;
import com.ikingtech.framework.sdk.user.api.UserApi;
import com.ikingtech.framework.sdk.user.model.UserBasicDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import com.ikingtech.platform.business.message.entity.MessageDO;
import com.ikingtech.platform.business.message.exception.MessageExceptionInfo;
import com.ikingtech.platform.business.message.service.MessageService;
import lombok.RequiredArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author tie yan
 */
@RequiredArgsConstructor
@ApiController(value = "/message/management", name = "消息中心-消息管理", description = "消息中心-消息管理")
public class MessageManagementController implements MessageManagementApi {

    private final MessageService service;

    private final UserApi userApi;

    @Override
    public R<List<MessageDTO>> page(MessageQueryParamDTO queryParam) {
        PageResult<MessageDO> entities = this.service.listPage(queryParam);
        List<UserBasicDTO> users = this.userApi.listInfoByIds(BatchParam.build(Tools.Coll.convertList(entities.getData(), MessageDO::getReceiverId))).getData();
        Map<String, UserBasicDTO> userMap = Tools.Coll.convertMap(users, UserBasicDTO::getId);
        return R.ok(entities.getPages(), entities.getTotal(), Tools.Coll.convertList(entities.getData(), entity -> {
            MessageDTO message = Tools.Bean.copy(entity, MessageDTO.class);
            if (null != message.getChannel()) {
                message.setChannelName(message.getChannel().description);
            }
            if (null != message.getDeliverStatus()) {
                message.setDeliverStatusName(message.getDeliverStatus().description);
            }
            if (null != message.getReadStatus()) {
                message.setReadStatusName(message.getReadStatus().description);
            }
            if (null != message.getDeliverStatus()) {
                message.setDeliverStatusName(message.getDeliverStatus().description);
            }
            if (userMap.containsKey(entity.getReceiverId())) {
                message.setReceiverName(userMap.get(entity.getReceiverId()).getName());
            }
            return message;
        }));
    }

    @Override
    public R<Object> readById(String id) {
        MessageDO entity = this.service.getById(id);
        if (null == entity) {
            throw new FrameworkException(MessageExceptionInfo.MESSAGE_NOT_FOUND);
        }
        entity.setReadStatus(MessageReadStatusEnum.READ.name());
        entity.setReadTime(LocalDateTime.now());
        this.service.updateById(entity);
        return R.ok();
    }

    @Override
    public R<Object> readAll() {
        List<MessageDO> entities = this.service.listByReadStatusAndReceiverId(MessageReadStatusEnum.NO_READ, Me.id());
        this.service.updateBatchById(Tools.Coll.traverse(entities, entity -> {
            entity.setReadStatus(MessageReadStatusEnum.READ.name());
            entity.setReadTime(LocalDateTime.now());
            return entity;
        }));
        return R.ok();
    }

    @Override
    public R<Object> send(MessageSendParam sendParam) {
        this.service.send(sendParam);
        return R.ok();
    }
}
